Categories
React Tips

React Tips — Disable Buttons, FormData, Types for Function

Spread the love

React is a popular library for creating web apps and mobile apps.

In this article, we’ll look at some tips for writing better React apps.

Send Multipart Form Data with Axios in a React Component

We can send form data with the FormData constructor.

We can pass that straight into the Axios post method.

For instance, we can write:

import React from 'react'
import axios, { post } from 'axios';

class App extends React.Component {

  constructor(props) {
    super(props);
    this.state ={
      file:null
    }
    this.onFormSubmit = this.onFormSubmit.bind(this)
    this.onChange = this.onChange.bind(this)
    this.fileUpload = this.fileUpload.bind(this)
  }

  onFormSubmit(e){
    e.preventDefault()
    const url = 'http://example.com/upload';
    const formData = new FormData();
    formData.append('file', this.state.file);
    const config = {
      headers: {
        'content-type': 'multipart/form-data'
      }
    }
    post(url, formData, config);
      .then((response) => {
        console.log(response.data);
      })
  }

  onChange(e) {
    this.setState({ file: e.target.files[0 ]})
  }

  render() {
    return (
      <form onSubmit={this.onFormSubmit}>
        <h1>File Upload</h1>
        <input type="file" onChange={this.onChange} />
        <button type="submit">Upload</button>
      </form>
   )
  }
}

We have a file input, where we set the file input to the file that’s submitted in the onChange method.

We save the selected file object as the value of the file state.

Then when we click the Upload button, onFormSubmit is run.

In the method, we created a FomrData instance.

Then we append our file into the FormData instance.

We also set the header so that we indicate that we’re sending form data.

Once we did that, we proceed with our file upload.

Disable Button with React

We can disable a button with React by setting the disabled prop of the button.

For instance, we can write:

<button disabled={!this.state.value} />

We can use it in a component by writing:

class ItemForm extends React.Component {
  constructor() {
    super();
    this.state = { value: '' };
    this.onChange = this.onChange.bind(this);
    this.add = this.add.bind(this);
  }

  add() {
    this.props.addItem(this.state.value);
    this.setState({ value: '' });
  }

  onChange(e) {
    this.setState({ value: e.target.value });
  }

  render() {
    return (
      <div>
        <input
          type="text"
          value={this.state.value}
          onChange={this.onChange}
          placeholder='item name'
        />
        <button
          disabled={!this.state.value}
          onClick={this.add}
        >
          Add
        </button>
      </div>
    );
  }

We pass in the value state to let us enter the data that we want into the input field.

Then we check that in disabled prop of the button.

This way, the button is disabled if we have nothing inputted into the form field.

Cannot Read Property ‘map’ of Undefined

We may get this if we try to call map on something that doesn’t have a map method.

This may happen to something that we expect to be an array, but it’s not.

Therefore, we should check if the value we’re calling map on is an array before doing anything.

For instance, we can do that by writing:

if (Array.isArray(this.props.data)) {
  const commentNodes = this.props.data.map((comment) => {
    return (
      <div>
        <h1>{comment.title}</h1>
      </div>
    );
  });
}

We called Array.isArray to check if this.props.data is an array.

If it is, then we call map to map the data prop to h1 elements.

How to Add Custom HTML Attributes in JSX

With React 16, we can add custom attributes natively.

For instance, we can write:

render() {
  return (
    <div data-foo="bar" />
  );
}

We can just add it straight into our HTML elements without doing anything special.

Use Children with React Stateless Functional Component in TypeScript

We can pass in the interface or type alias into the generic type argument of React.FunctionComponent to set the type for ur props.

As long as the alias or interface has the children prop, we can use the children prop.

For instance, we can write:

const Foo: React.FunctionComponent<FooProps> = props => (
  <div>
    <p>{props.bar}</p>
    <p>{props.children}</p>
  </div>
);

FooProps has the bar and children entries, so we can reference both in our component.

React.FC is the shorthand for React.FunctionComponent .

Before React 16.8, we use the React.StatelessComponent type instead.

For instance, we can write:

const Foo: React.StatelessComponent<{}> = props => (
  <div>{props.children}</div>
);

or:

const Foo : React.StatelessComponent<FooProps> = props => (
  <div>
    <p>{props.propInMyProps}</p>
    <p>{props.children}</p>
  </div>
);

React.SFC is the shorthand for React.StatelessComponent.

Conclusion

We can add types to stateless components with TypeScript.

Sending multipart form data can be done with the FormData constructor.

Also, we should make sure that we have an array before calling map on it.

We can conditionally disable buttons with React.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *